LScript User Guide
Next Section Previous Section Table of Contents Index Errata

Inside LScript

In the following sections we will cover details of LScript through examination of the language syntax, variables, control structures, commands and functions.

LScript Structure

An LScript is structured much like a C program. Each script that you write can have as little as one procedure, or as many as you need (and your computer's memory allows). Each LScript must contain at least one procedure, and it must be labeled as "main."

     main
     {
         ...
     }

The "main" Procedure

Execution of an LScript is always controlled by the main() procedure. All processing within your script can take place within this single procedure, or you may use the main() procedure to selectively execute other procedures belonging to your script. These other procedures can take the form of built-ins (those that are internal to the LScript Scripting Plugin), or those that you (or others) have defined as scripting procedures. These non-internal scripting procedures are often referred to as "user-defined procedures."

Variable Assignment

Variables in LScript are typeless, and need not be explicitly declared before being used. They do, however, need to be explicitly assigned a value before they are employed within script code.

To assign a value to a variable, it needs to be placed on the left-hand side of an assignment, indicated by the presence of an assignment token. This assignment token is the equals sign (=). Values to be assigned to a variable are derived, either explicitly or implicitly, from expressions that will appear on the right-hand side of the assignment. Explicit values are generally those of a literal nature (i.e., "a string" or 15.54), while implicit values tend to come from calculations of some kind (i.e., a function call or mathematical operation).

     main
     {
        myvar = "testing";      // 'myvar' is now a string
        num = 15.4 * sqrt(4.3493);  // 'num' becomes a floating-point value
     }
Variables that are typeless can hold data of any type supported by LScript. You need do nothing explicit or special to assign values to an LScript variable. A variable "becomes" the data that is assigned to it.
     main
     {
        myvar = "testing";      // 'myvar' is a string
        myvar = 15.4 * sqrt(4.3493);  // now 'myvar' is a floating-point value
     }

Associative Assignments

If the expression on the right-hand side of the assignment evaluates to more than one item, LScript will automatically create a structure known as an
array to house all the values being assigned. This is the implicit behavior programmed into LScript to prevent data loss. You can, however, override LScript's natural tendency to create arrays for multiple return values by using what is known as an "associative assignment."

An associative assignment is a method whereby the position (or index) of a returned item is associated with, and assigned to, a variable whose position (or index) matches. By way of example, let's say that a function was invoked in the right-hand side of an assignment that returned four values. If you were to assign this return data to a single variable, LScript would automatically create an array to house these values, and assign that to the variable instead:

     ...
     data = split(path);
     ...
The function invoked is designed to return four string values. In the example above, the 'data' variable would become an array of four elements, each holding the values returned from the function.

However, what if we were only interested in the first value being returned? We could tell LScript explicitly how to handle this situation by using an associative assignment. In such an assingment, we would "wrap" our variable (or variables, if we wanted to retrieve more than just the first returned value) in parentheses to protect it from becoming an array. Its position within this wrapping would determine which returned value it would receive. For instance:

     ...
     (data) = split(path);
     ...
In this case, our variable 'data' is occupying the first position in the associative wrapper. Therefore, the first return value from the function call will be assigned to it. All other returned values would be discarded. Were we interested in the first two values, we might change our code accordingly:

     ...
     (data1,data2) = split(path);
     ...
Now, we have gathered up the first two returned values, while the remaining two values are discarded and lost.

If you were only intersted in, say, the third return value, you must provide containers to retreive all values leading up to the one in which you are interested:

     ...
     (d1,d2,file) = split(path);  // only want 'file'
     ...

User-defined Procedures

A user-defined procedure can be created within your script by declaring a name for your procedure, followed by an opening brace ('{') and terminated by a closing brace ('}'). An alternate syntax can be used that replaces the opening brace with the keyword begin and the closing brace with the keyword end.

User-defined procedures can also optionally accept one or more calling arguments. These argument declarations follow the procedure name, and are prefaced by a colon (':').

User-defined procedures also have the ability to return one or more values to the caller by using the return command. A return command can return two or more values by separating them with a comma (','). When a user-defined function returns more than one value, the receiving variable would ideally be of type array. However, the LScript language does not enforce this, so the receiving variable, if not an array, will be assigned the first return value while all remaining values are discarded. If a variable of type array is used, it is not required to be of the same size as the return argument count of the user-defined procedure. Those return values whose position exceeds the array size will simply be discarded.

By way of example, let's create a user-defined function to select a particular value if the first argument is non-zero, and select another value if it determines that the first argument is equal to zero. We'll call the new procedure which, and it could be written in the follow manner:

     main
     {
         ...
         t = which(val1,val2,val3);
         ...
     }

     which: v1,v2,v3
     {
         if(v1)
          return(v2);
         else
          return(v3);
     }

Libraries

User-defined procedures can also be housed in LScript libraries. LScript libraries are much like LScripts with the exception that they cannot contain a main() function, nor can they declare global variables.

When you direct LScript to process a library for your script, you employ the library directive. When encountered, LScript will scan through the specified library looking for user-defined procedures that satisfy unresolved references made in your primary script. Only those user-defined procedures that satisfy an unresolved external reference will be loaded into your script's run-time space for execution. Other library procedures that have no relevance to your script will be ignored by LScript (you can modify this behavior by using the loadall pragma directive, which is discussed later in this document).

Libraries are accessed by placing a library command in your script at the global level (i.e., outside all declared functions), and following it with the name of the library file. For example,

     library "mylib.lib";

     main
     {
         ...
     }
The example LScript file2.ls, include on your distribution diskette, illustrates the use of LScript╞s library feature by loading a library file (file2.lib) to accomplish its task. Library files can have any filename you wish. LScript does not enforce any sort of naming convention where libraries are concerned.

LScript also allows you to specify default libraries that will be loaded automatically when each script is executed.


Next Section Previous Section Table of Contents Index Errata
© 1996 Virtual Visions, Inc.
© 1997 NewTek, Inc.